home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / metkit / setup.exe / EXAMPLES / CATFISH / SETUPDLG.CPP < prev    next >
C/C++ Source or Header  |  1997-06-08  |  10KB  |  356 lines

  1. //    Copyright (C) 1996, 1997 Meta Four Software.  All rights reserved.
  2. //
  3. //    Setup dialog sample code
  4. //
  5. //! rev="$Id: setupdlg.cpp,v 1.4 1997/05/27 00:06:17 jcw Rel $"
  6.  
  7. #include "stdafx.h"
  8. #include "catfish.h"
  9. #include "setupdlg.h"
  10. #include "pickdir.h"
  11.  
  12.     // the data structure used in the catalog, required for MetaKit version 1
  13. #define CAT_FORMAT  "dirs[parent:I,name:S,files[name:S,size:I,date:I]]"
  14.     
  15. #ifdef _DEBUG
  16. #undef THIS_FILE
  17. static char BASED_CODE THIS_FILE[] = __FILE__;
  18. #endif
  19.  
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CSetupDialog dialog
  22.  
  23. CSetupDialog::CSetupDialog(CWnd* pParent /*=NULL*/)
  24.     : CDialog(CSetupDialog::IDD, pParent),
  25.       m_exists (FALSE), m_timer (0), m_allowScan (FALSE)
  26. {
  27.     //{{AFX_DATA_INIT(CSetupDialog)
  28.     m_name = "";
  29.     //}}AFX_DATA_INIT
  30. }
  31.  
  32. void CSetupDialog::DoDataExchange(CDataExchange* pDX)
  33. {
  34.     CDialog::DoDataExchange(pDX);
  35.     //{{AFX_DATA_MAP(CSetupDialog)
  36.     DDX_Control(pDX, IDOK, m_okBtn);
  37.     DDX_Control(pDX, IDC_BROWSE_BTN, m_browseBtn);
  38.     DDX_Control(pDX, IDC_DEL_BTN, m_deleteBtn);
  39.     DDX_Control(pDX, IDC_ADD_BTN, m_addBtn);
  40.     DDX_Control(pDX, IDC_UPDATE_BTN, m_updateBtn);
  41.     DDX_Control(pDX, IDC_STATUS, m_status);
  42.     DDX_Control(pDX, IDC_ROOT, m_root);
  43.     DDX_Text(pDX, IDC_NAME, m_name);
  44.     //}}AFX_DATA_MAP
  45. }
  46.  
  47. BEGIN_MESSAGE_MAP(CSetupDialog, CDialog)
  48.     //{{AFX_MSG_MAP(CSetupDialog)
  49.     ON_BN_CLICKED(IDC_ADD_BTN, OnAddBtn)
  50.     ON_BN_CLICKED(IDC_UPDATE_BTN, OnUpdateBtn)
  51.     ON_BN_CLICKED(IDC_DEL_BTN, OnDelBtn)
  52.     ON_BN_CLICKED(IDC_BROWSE_BTN, OnBrowseBtn)
  53.     ON_EN_CHANGE(IDC_NAME, OnChangeName)
  54.     ON_EN_CHANGE(IDC_ROOT, OnChangeRoot)
  55.     ON_WM_TIMER()
  56.     ON_EN_KILLFOCUS(IDC_ROOT, OnKillfocusRoot)
  57.     ON_WM_CLOSE()
  58.     //}}AFX_MSG_MAP
  59. END_MESSAGE_MAP()
  60.  
  61. /////////////////////////////////////////////////////////////////////////////
  62. // CSetupDialog message handlers
  63.  
  64. void CSetupDialog::Execute(BOOL now)
  65. {             
  66.     m_scanNow = now;
  67.     
  68.     DoModal();
  69. }
  70.  
  71.     // this member is called by the ScanDisk code during its (lengthy) scan
  72. bool CSetupDialog::UpdateStatus(const char* text)
  73. {
  74.     static DWORD lastTick = 0;
  75.     
  76.         // a null pointer forces immediate clear of the status text
  77.     if (!text)
  78.     {
  79.         lastTick = 0;
  80.         text = "";
  81.     }
  82.     
  83.         // only refresh the status message every quarter second
  84.     if (GetTickCount() > lastTick + 250)
  85.     {
  86.         lastTick = GetTickCount();
  87.         m_status.SetWindowText(text);   
  88.     }
  89.     
  90.     return cStatusHandler::UpdateStatus(text) && m_allowScan;
  91. }
  92.  
  93.     // the name has changed, update other fields (either now, or a little later)
  94.     // this delay is used to avoid excessive activity while a name is typed in
  95. void CSetupDialog::NameChange(BOOL delay)
  96. {
  97.     CString s;
  98.     if (m_name.IsEmpty())
  99.         s = "(please enter name of catalog)";
  100.     m_status.SetWindowText(s);
  101.  
  102.     m_exists = FALSE;
  103.     
  104.     if (delay)
  105.     {       // arm the timer (if there is a catalog name)
  106.         KillTimer(m_timer);
  107.         m_timer = m_name.IsEmpty() ? 0 :
  108.                     SetTimer(1, 500, 0); // timeout in 500 mS
  109.     }
  110.     else
  111.         InspectCatalog();
  112. }
  113.  
  114.     // scan through the directories, but be prepared to deal with premature abort
  115. void CSetupDialog::ScanDirectories()
  116. {
  117.     CString s;
  118.     m_root.GetWindowText(s);
  119.     
  120.         // prepare for a lengthy scan with a cancel option
  121.     AdjustButtons(TRUE);                        
  122.                             
  123.     m_okBtn.EnableWindow(FALSE);
  124.     m_browseBtn.SetWindowText("Abort");
  125.     SetDefID(IDC_BROWSE_BTN);
  126.  
  127.     m_allowScan = TRUE;
  128.                             
  129.         // build a catalog of the specified directory tree
  130.     c4_View dirs = fScanDirectories(s, this);
  131.                             
  132.         // restore normal situation
  133.     m_allowScan = FALSE;
  134.     m_okBtn.EnableWindow(TRUE);
  135.     if (m_scanNow)
  136.         m_browseBtn.EnableWindow(FALSE);
  137.     else
  138.         m_browseBtn.SetWindowText("Browse");
  139.                             
  140.     m_status.SetWindowText("Saving catalog...");
  141.         // saving may take a litle time
  142.     HCURSOR oldCursor = SetCursor(LoadCursor(0, IDC_WAIT));
  143.     
  144.     if (dirs.GetSize() > 0)
  145.     {                        
  146.         s = m_name + FILE_TYPE;
  147.                                 
  148.             // clumsy, remove file to create smallest file
  149.         CFileStatus fs;
  150.         if (CFile::GetStatus(s, fs))
  151.             CFile::Remove(s);
  152.                                 
  153.             // this stores the catalog on file  
  154.         c4_Storage storage (s, CAT_FORMAT);
  155.         storage.View("dirs") = dirs;
  156.         storage.Commit();
  157.     }
  158.                             
  159.     SetCursor(oldCursor);
  160.     
  161.     InspectCatalog();
  162. }     
  163.  
  164.     // go see if the catalog exists and get its file date and root path
  165. void CSetupDialog::InspectCatalog()
  166. {
  167.     UpdateData();
  168.                             
  169.     CString s = GetCatalogDate(m_name);
  170.     if (!s.IsEmpty())
  171.         s = "Last change:  " + s;
  172.  
  173.     UpdateData(FALSE); // adjusts the name
  174.                                                             
  175.     m_status.SetWindowText(s);
  176.     m_exists = !s.IsEmpty();
  177.                                 
  178.     if (m_exists)
  179.     {
  180.             // load the root path name from the catalog
  181.             // this is quick, due to on-demand loading
  182.         c4_Storage storage (m_name + FILE_TYPE, false);
  183.         c4_View dirs = storage.View("dirs");
  184.         m_origRoot = pName (dirs[0]);
  185.         m_root.SetWindowText(m_origRoot);
  186.     }
  187. }
  188.  
  189.     // adjust the button dimming and titles to reflect the current situation
  190. void CSetupDialog::AdjustButtons(BOOL inScan_)
  191. {
  192.     CString s;
  193.     m_root.GetWindowText(s);
  194.     BOOL valid = !s.IsEmpty() && !inScan_;
  195.     
  196.         // don't enable buttons while the timer is running  
  197.     m_addBtn.EnableWindow(valid && !m_exists && !m_timer && !m_name.IsEmpty());
  198.     
  199.     ASSERT(!(m_exists && m_timer)); // if it exists, timer cannot be running
  200.     m_updateBtn.EnableWindow(valid && m_exists);
  201.     m_deleteBtn.EnableWindow(valid && m_exists);
  202.     
  203.         // The default button is "OK" for existing files
  204.         // If the root has been set for a new file, the default is "Add"
  205.         // For new files, or if the root is different, the default is "Browse"
  206.         // Never make "Change" the default, since that is a dangerous change
  207.     SetDefID(valid &&  m_exists && s == m_origRoot ? IDOK :
  208.              valid && !m_exists && !m_timer        ? IDC_ADD_BTN : 
  209.                                                      IDC_BROWSE_BTN);
  210.     
  211.     if (!GetFocus())
  212.         m_okBtn.SetFocus();
  213. }
  214.                             
  215.         // called shortly after a change to the name or root edit control       
  216. void CSetupDialog::OnTimer(UINT nIDEvent)
  217. {
  218.     KillTimer(m_timer);
  219.     m_timer = 0;
  220.     
  221.     InspectCatalog();
  222.     OnChangeRoot();
  223.     
  224.     CDialog::OnTimer(nIDEvent);
  225. }
  226.             
  227. BOOL CSetupDialog::OnInitDialog()
  228. {
  229.     CenterWindow();
  230.     CDialog::OnInitDialog();
  231.     
  232.     m_nameEditCtrl.SubclassDlgItem(IDC_NAME, this);
  233.     
  234.     NameChange(FALSE);
  235.     AdjustButtons();
  236.     
  237.     if (m_scanNow) 
  238.     {
  239.         SetWindowText("Re-scanning disk...");
  240.         
  241.         CRect r1, r2;
  242.         GetWindowRect(&r1);
  243.         m_okBtn.GetWindowRect(&r2);
  244.         r1.bottom = r2.top;
  245.             // reduce window height by dropping the bottom row of buttons
  246.         VERIFY(SetWindowPos(&wndTop, 0, 0, r1.Width(), r1.Height(),
  247.                                 SWP_NOMOVE | SWP_SHOWWINDOW));  
  248.         UpdateWindow(); 
  249.     
  250.         OnUpdateBtn();
  251.         OnOK();
  252.     }
  253.         
  254.     return TRUE;  // return TRUE  unless you set the focus to a control
  255. }
  256.  
  257. void CSetupDialog::OnCancel()
  258. {
  259.     if (m_allowScan)
  260.         m_allowScan = FALSE;
  261.     else
  262.         CDialog::OnCancel();
  263. }
  264.  
  265. void CSetupDialog::OnClose()
  266. {
  267.     if (m_allowScan)
  268.         m_allowScan = FALSE;
  269.     else
  270.         EndDialog(IDOK);    // can't use close box during scan
  271. }
  272.  
  273. void CSetupDialog::OnAdd